﻿using AutoMapper;
using KC.DataAccess.Account.Repository;
using KC.Domain.Core.IRepository;
using KC.Framework.Exceptions;
using KC.Framework.Extension;
using KC.Framework.Tenant;
using KC.Model.Account;
using KC.Service.Core.EFService;
using KC.DTO.Account;
using KC.DTO.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using KC.Service.Core.WebApiService.Business;

namespace KC.Service.Account
{
    public class SysManageService : EFServiceBase, ISysManageService
    {
        #region Db Repository

        private IOrganizationRepository _organizationRepository;
        private IDbRepository<UserTracingLog> _userTracingLogRepository;

        #endregion

        //public SysManageService(
        //    Tenant tenant,
        //    System.Net.Http.IHttpClientFactory clientFactory)
        //    : base(tenant, clientFactory)
        //{
        //    var unitOfWorkContext = new ComAccountUnitOfWorkContext(tenant);
        //    _orgnizationRepository = new OrganizationRepository(unitOfWorkContext);
        //    _userTracingLogRepository = new CommonEFRepository<UserTracingLog>(unitOfWorkContext);
        //}

        public SysManageService(
            Tenant tenant,
            IAccountApiService accountApiService,
            ITenantUserApiService tenantUserApiService,
            IConfigApiService configApiService,
            IOrganizationRepository orgnizationRepository,
            IDbRepository<UserTracingLog> userTracingLogRepository,
            System.Net.Http.IHttpClientFactory clientFactory,
            Microsoft.Extensions.Logging.ILogger<SysManageService> logger)
            : base(tenant, accountApiService, tenantUserApiService, configApiService, clientFactory, logger)
        {
            //AccountUnitOfWorkContext = new ComAccountUnitOfWorkContext(base.Tenant);

            _organizationRepository = orgnizationRepository;
            _userTracingLogRepository = userTracingLogRepository;
        }

        #region Organization
        public bool ExistOrganizationName(int id, string name)
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name", "name is null or empty.");

            Expression<Func<Organization, bool>> predicate = m => !m.IsDeleted && m.Name.Equals(name);
            if (id != 0)
                predicate = predicate.And(c => c.Id != id);

            return _organizationRepository.ExistByFilter(predicate);
        }
        public List<OrganizationDTO> GetUsersByOrganizationsId(int id)
        {
            var result = _organizationRepository.GetUsersByOrganizationId(id);

            return Mapper.Map<List<OrganizationDTO>>(result);
        }

        public List<OrganizationDTO> GetAllOrganizationTrees()
        {
            Expression<Func<Organization, bool>> predicate = m => !m.IsDeleted;

            var data = _organizationRepository.GetAllTreeNodeWithNestChildByFilter(predicate);

            return Mapper.Map<List<OrganizationDTO>>(data);
        }

        public List<OrganizationDTO> GetOrganizationTreesByIds(List<int> orgIds)
        {
            Expression<Func<Organization, bool>> predicate = m => !m.IsDeleted;
            if (orgIds.Any())
            {
                predicate = predicate.And(m => orgIds.Contains(m.Id));
            }
            var data = _organizationRepository.GetAllTreeNodeWithNestChildByFilter(predicate);

            return Mapper.Map<List<OrganizationDTO>>(data);
        }

        public List<OrganizationDTO> GetOrganizationsTreesByName(string name)
        {
            Expression<Func<Organization, bool>> predicate = m => !m.IsDeleted;
            if (!string.IsNullOrWhiteSpace(name))
            {
                predicate = predicate.And(m => m.Name.Contains(name));
            }

            var data = _organizationRepository.GetTreeNodesWithNestParentAndChildByFilter(predicate);
            return Mapper.Map<List<OrganizationDTO>>(data);
        }
        //获取传入DTO的上级并加入到list
        private void organizationIdPar(OrganizationDTO parent, List<OrganizationDTO> list)
        {
            //获取全部
            var allOrgs = _organizationRepository.GetAllOrganizationsWithUsers(c => !c.IsDeleted);
            //获取传入DTO的父级菜单
            var child = allOrgs.Where(m => m.Id.Equals(parent.ParentId)).ToList();
            var orgDtoWithUsers = Mapper.Map<List<OrganizationDTO>>(child);
            foreach (var organization in orgDtoWithUsers)
            {
                if (organization.ParentId != null)
                {
                    var bools = list.Count(c =>
                    {
                        var firstOrDefault = orgDtoWithUsers.FirstOrDefault();
                        return firstOrDefault != null && c.id == firstOrDefault.id;
                    }) > 0;
                    if (!bools)
                    {
                        list.Add(orgDtoWithUsers.FirstOrDefault());
                    }
                    organizationIdPar(organization, list);
                }
                else
                {
                    var bools = list.Count(c =>
                    {
                        var firstOrDefault = orgDtoWithUsers.FirstOrDefault();
                        return firstOrDefault != null && c.id == firstOrDefault.id;
                    }) > 0;
                    if (!bools)
                    {
                        list.Add(orgDtoWithUsers.FirstOrDefault());
                    }
                }
            }
        }
        private void organizationIdSon(OrganizationDTO parent, List<int> list)
        {
            var allOrgs = _organizationRepository.GetAllOrganizationsWithUsers(c => !c.IsDeleted);
            var child = allOrgs.Where(m => m.Id.Equals(parent.ParentId)).ToList();
            var orgDtoWithUsers = Mapper.Map<List<OrganizationDTO>>(child);
            foreach (var organization in orgDtoWithUsers)
            {
                if (organization.ParentId != null)
                {
                    list.Add(organization.id);
                    organizationIdSon(organization, list);
                }
            }
        }

        //根据传入部门ID集合  查出所有该部门及其下属
        public List<OrganizationDTO> GetOrganizationsById(List<int> treeWhere)
        {
            if (treeWhere.Count() > 0)
            {
                Expression<Func<Organization, bool>> predicate = m => !m.IsDeleted && treeWhere.Contains(m.Id);
                var result = new List<OrganizationDTO>();
                var data = _organizationRepository.GetOrganizationsWithUsersByFilter(predicate, m => m.Index);
                var orgs = Mapper.Map<List<OrganizationDTO>>(data);
                var treeWhereMax = data.OrderBy(c => c.Level).GroupBy(c => c.Level).FirstOrDefault();
                var level = treeWhereMax.Key;
                var levelList = treeWhereMax.Where(c => c.Level == level).ToList();
                foreach (var organizationDto in levelList)
                {
                    //把子集菜单加到父集菜单中去
                    var orgsWherePar = orgs.Where(m => m.id == organizationDto.Id).ToList();
                    foreach (var parent in orgsWherePar)
                    {
                        NestOrganizationWithChild(parent, orgs);
                        result.Add(parent);
                    }
                }
                return result;
            }
            return null;
        }
        //根据传入部门ID集合  查出所有该部门及其下属的ID集合
        public List<int> GetOrganizationsByIdList(List<int> treeWhere)
        {
            var list = new List<int>();
            if (treeWhere.Count() > 0)
            {
                Expression<Func<Organization, bool>> predicate = m => !m.IsDeleted;
                var data = _organizationRepository.GetOrganizationsWithUsersByFilter(predicate, m => m.Index);
                var orgs = Mapper.Map<List<OrganizationDTO>>(data);
                //var treeWhereMax = treeWhere.OrderBy(c => c.Level).GroupBy(c => c.Level).FirstOrDefault();
                //var level = treeWhereMax.Key;
                for (int i = 0; i < treeWhere.Count(); i++)
                {
                    var levelList = orgs.FirstOrDefault(c => c.id == treeWhere[i]);
                    if (levelList != null)
                    {
                        list.Add(levelList.id);
                        //把子集菜单加到父集菜单中去
                        var orgsWherePar = orgs.Where(m => m.id == levelList.id).ToList();
                        foreach (var parent in orgsWherePar)
                        {
                            NestOrganizationWithID(parent, orgs, list);
                        }
                    }
                }

                return list.Distinct().ToList();
            }
            return list;
        }
        private void NestOrganizationWithID(OrganizationDTO parent, List<OrganizationDTO> allOrgs, List<int> list)
        {
            var child = allOrgs.Where(m => m.ParentId.Equals(parent.id)).ToList();
            parent.children = child;
            foreach (var children in child.OrderBy(m => m.Index))
            {
                children.ParentName = parent.text;
                list.Add(children.id);
                NestOrganizationWithID(children, allOrgs, list);
            }
        }

        public List<OrganizationDTO> GetOrganizationsWithUsers()
        {
            Expression<Func<Organization, bool>> predicate = m => !m.IsDeleted;

            var result = new List<OrganizationDTO>();
            var data = _organizationRepository.GetAllOrganizationsWithUsers(predicate);
            var orgs = data.Select(m => AppendOrgWithUsers(m)).ToList();
            foreach (var parent in orgs.Where(m => m.ParentId == null))
            {
                NestOrganizationWithChild(parent, orgs);
                result.Add(parent);
            }
            return result;
        }
        public List<OrganizationDTO> GetOrganizationsWithUsersByRoleIds(List<string> roleIds)
        {
            if (roleIds == null || !roleIds.Any())
                return GetOrganizationsWithUsers();

            var result = new List<OrganizationDTO>();
            var data = _organizationRepository.GetAllOrganizationsWithUsers(c => !c.IsDeleted);
            var orgs = data.Select(m => AppendOrgWithUsers(m, roleIds)).ToList();
            foreach (var parent in orgs.Where(m => m.ParentId == null))
            {
                NestOrganizationWithChild(parent, orgs);
                result.Add(parent);
            }
            return result;
        }
        public List<OrganizationDTO> GetRootOrganizationsWithUsersByOrgIds(Guid appid, List<int> orgIds)
        {
            if (orgIds == null || !orgIds.Any())
                return GetOrganizationsWithUsers();

            var result = new List<OrganizationDTO>();
            var data = _organizationRepository.GetAllOrganizationsWithUsers(c => !c.IsDeleted && orgIds.Contains(c.Id));
            var orgs = data.Select(m => AppendOrgWithUsers(m, null)).ToList();
            foreach (var parent in orgs.Where(m => m.ParentId == null))
            {
                NestOrganizationWithChild(parent, orgs);
                result.Add(parent);
            }
            return result;
        }
        /// <summary>
        /// 查询部门或角色的组织框架（审批中心流程排除选择）
        /// </summary>
        /// <param name="roleIds"></param>
        /// <param name="depIds"></param>
        /// <returns></returns>
        public List<OrganizationDTO> GetOrgsWithUsersByRoleIdsAndOrgids(List<string> roleIds, List<int> depIds)
        {
            if ((roleIds == null || !roleIds.Any()) && (depIds == null || !depIds.Any()))
            {
                return GetOrganizationsWithUsers();
            }
            else if ((depIds == null || !depIds.Any()))
            {
                return GetOrganizationsWithUsersByRoleIds(roleIds);
            }

            var result = new List<OrganizationDTO>();
            var data = GetOrganizationsByIds(depIds);
            data.ForEach(org =>
            {
                var orgWithChild = GetOrganizationsWithUsersByOrgId(org.id);
                org.children = orgWithChild.children;
            });
            foreach (var parent in data)
            {
                NestOrganizationWithChild(parent, data);
                result.Add(parent);
            }
            return result;
        }
        public List<OrganizationDTO> GetOrganizationsByIds(List<int> organizationIds)
        {
            Expression<Func<Organization, bool>> predicate = m => true;
            if (organizationIds.Any())
            {
                predicate = predicate.And(m => organizationIds.Contains(m.Id));
            }

            var data = _organizationRepository.Find(predicate, m => m.Index);
            var rows = Mapper.Map<List<OrganizationDTO>>(data);
            return rows;
        }

        public List<OrganizationDTO> GetWorkFlowSelectUser()
        {
            var temp = _organizationRepository.GetAllOrganizationsWithUsers(c => !c.IsDeleted);
            return new List<OrganizationDTO>();
        }

        public List<OrganizationDTO> GetOrganizationsWithUsersByUserId(string userId)
        {
            if (string.IsNullOrEmpty(userId))
                return new List<OrganizationDTO>();

            var result = new List<OrganizationDTO>();
            var data = _organizationRepository.GetAllOrganizationsWithUsers(c => !c.IsDeleted && c.Users.Select(u => u.Id).ToList().Contains(userId));
            var orgs = data.Select(m => AppendOrgWithUsers(m, null)).ToList();
            return orgs;
        }

        public PaginatedBaseDTO<OrganizationDTO> GetPaginatedOrganizationsWithUsers(Guid appid, int pageIndex, int pageSize)
        {
            Expression<Func<Organization, bool>> predicate = m => !m.IsDeleted;
            var result = new List<OrganizationDTO>();
            var data = _organizationRepository.GetAllOrganizationsWithUsers(predicate);
            var orgs = data.Select(m => AppendOrgWithUsers(m)).ToList();
            foreach (var parent in orgs.Where(m => m.ParentId == null))
            {
                NestOrganizationWithChild(parent, orgs);
                result.Add(parent);
            }
            var total = result.Count;
            var rows = result.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            return new PaginatedBaseDTO<OrganizationDTO>(pageIndex, pageSize, total, Mapper.Map<List<OrganizationDTO>>(rows));
        }
        public PaginatedBaseDTO<OrganizationDTO> GetPaginatedOrganizationsWithUsersByFilter(Guid appid, List<string> roleIds, string departName, string departCode, string userName, string userCode, string searchKey, int pageIndex, int pageSize)
        {
            if (roleIds == null
                && string.IsNullOrWhiteSpace(departName)
                && string.IsNullOrWhiteSpace(departCode)
                && string.IsNullOrWhiteSpace(userName)
                && string.IsNullOrWhiteSpace(userCode))
                return GetPaginatedOrganizationsWithUsers(appid, pageIndex, pageSize);

            var result = new List<OrganizationDTO>();
            Expression<Func<Organization, bool>> predicate = c => !c.IsDeleted;
            if (!string.IsNullOrWhiteSpace(departName) || !string.IsNullOrWhiteSpace(departCode))
            {
                switch (searchKey)
                {
                    case "name":
                        predicate = predicate.And(c => c.Name.Contains(departName));
                        break;
                    case "code":
                        predicate = predicate.And(c => c.TreeCode.Contains(departCode));
                        break;
                }

            }
            var total = 0;
            var rows = new List<OrganizationDTO>();
            var data = _organizationRepository.GetAllOrganizationsWithUsersByUser(predicate, userName, userCode, searchKey);
            if (data.Count == 0)
            {
                return new PaginatedBaseDTO<OrganizationDTO>(pageIndex, pageSize, total, Mapper.Map<List<OrganizationDTO>>(rows));
            }
            var orgs = data.Select(m => AppendOrgWithUsers(m, roleIds)).ToList();
            foreach (var parent in orgs)
            {
                NestOrganizationWithChild(parent, orgs);
                result.Add(parent);
            }
            if (searchKey == "username" || searchKey == "usercode")
            {
                total = result.Count;
                rows = result.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                return new PaginatedBaseDTO<OrganizationDTO>(pageIndex, pageSize, total, Mapper.Map<List<OrganizationDTO>>(rows));
            }
            rows = result.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            return new PaginatedBaseDTO<OrganizationDTO>(pageIndex, pageSize, total, Mapper.Map<List<OrganizationDTO>>(rows));
        }

        /// <summary>
        /// 获取部门根据其fid
        /// </summary>
        /// <param name="orgfid"></param>
        /// <returns></returns>
        public OrganizationDTO GetOrganizationByFid(string orgfid)
        {
            Expression<Func<Organization, bool>> predicate = m => !m.IsDeleted;
            if (!string.IsNullOrWhiteSpace(orgfid))
            {
                predicate = predicate.And(c => c.ReferenceId1 == orgfid);
            }

            var data = _organizationRepository.FindByFilter(predicate);
            return Mapper.Map<OrganizationDTO>(data);
        }

        /// <summary>
        /// 获取所有部门(不是树状结构)
        /// </summary>
        /// <returns></returns>
        public List<OrganizationDTO> GetAllOrganization()
        {
            var data = _organizationRepository.Find(c => !c.IsDeleted);
            return Mapper.Map<List<OrganizationDTO>>(data);
        }

        public OrganizationDTO GetOrganizationById(int id)
        {
            var data = _organizationRepository.FindById(id);
            return Mapper.Map<OrganizationDTO>(data);
        }
        public OrganizationDTO GetOrganizationsWithUsersByOrgId(int orgId)
        {
            var data = _organizationRepository.GetOrganizationsAndUsersByOrgId(orgId);
            return AppendOrgWithUsers(data);
        }

        public bool AddOrganization(OrganizationDTO data)
        {
            var model = Mapper.Map<Organization>(data);
            return _organizationRepository.Add(model);
        }
        public bool SaveOrganization(OrganizationDTO data)
        {
            var model = Mapper.Map<Organization>(data);
            model.TreeCode = model.TreeCode.Trim();
            model.Name = model.Name.Trim();
            if (model.Id == 0)
            {
                var repeatTreeCodeTemp =
                    _organizationRepository.FindAll()
                        .Where(c => c.TreeCode == model.TreeCode && !c.IsDeleted && c.ParentId == model.ParentId)
                        .ToList();
                if (repeatTreeCodeTemp.Count > 0)
                {
                    throw new BusinessPromptException("部门代码【" + model.TreeCode + "】已存在,请重新输入！");
                }
                var repeatTreeNameTemp =
                    _organizationRepository.FindAll()
                        .Where(c => c.Name == model.Name && !c.IsDeleted && c.ParentId == model.ParentId)
                        .ToList();
                if (repeatTreeNameTemp.Count > 0)
                {
                    throw new BusinessPromptException("名称【" + model.Name + "】已存在,请重新输入！");
                }
                return _organizationRepository.Add(model);
            }
            else
            {
                var repeatTreeCodeTemp =
                    _organizationRepository.FindAll()
                        .Where(c => c.TreeCode == model.TreeCode && !c.IsDeleted && c.Id != model.Id && c.ParentId == model.ParentId)
                        .ToList();
                if (repeatTreeCodeTemp.Count > 0)
                {
                    throw new BusinessPromptException("部门代码【" + model.TreeCode + "】已存在,请重新输入！");
                }
                var repeatTreeNameTemp =
                    _organizationRepository.FindAll()
                        .Where(c => c.Name == model.Name && !c.IsDeleted && c.ParentId == model.ParentId && c.Id != model.Id)
                        .ToList();
                if (repeatTreeNameTemp.Count > 0)
                {
                    throw new BusinessPromptException("名称【" + model.Name + "】已存在,请重新输入！");
                }
                return _organizationRepository.Modify(model);
            }


        }
        public bool RemoveOrganization(int id)
        {
            Expression<Func<Organization, bool>> predicate = m => m.Id == id;
            var item = _organizationRepository.GetRootOrganizations(predicate).FirstOrDefault();
            item.IsDeleted = true;
            //return _orgnizationRepository.Remove(id);
            var data = Mapper.Map<OrganizationDTO>(item);
            return SaveOrganization(data);
        }

        private void NestOrganizationWithChild(OrganizationDTO parent, List<OrganizationDTO> allOrgs)
        {
            var child = allOrgs.Where(m => m.ParentId.Equals(parent.id)).ToList();
            parent.children = child;
            foreach (var children in child.OrderBy(m => m.Index))
            {
                children.ParentName = parent.text;
                NestOrganizationWithChild(children, allOrgs);
            }
        }
        private OrganizationDTO AppendOrgWithUsers(Organization data, List<string> roleIds = null)
        {
            var result = Mapper.Map<OrganizationDTO>(data);
            if (!data.OrganizationUsers.Any()) return result;

            if (roleIds == null)
            {
                result.Users = Mapper.Map<List<UserDTO>>(data.Users);
            }
            else
            {
                var selectUsers = data.OrganizationUsers
                    .Select(m => m.User)
                    .Where(m => m.UserRoles.Select(r => r.RoleId).Intersect(roleIds).Any());
                result.Users = Mapper.Map<List<UserDTO>>(selectUsers);
            }
            return result;
        }



        public List<UserDTO> GetUsersByOrgId(int id)
        {
            var data = _organizationRepository.GetUsersByOrgId(id);
            return Mapper.Map<List<UserDTO>>(data);
        }
        public List<UserDTO> GetUsersByOrgIds(List<int> ids)
        {
            var data = _organizationRepository.GetUsersByOrgIds(ids);
            return Mapper.Map<List<UserDTO>>(data);
        }

        /// <summary>
        /// 根据部门id获取部门下人员,不含下级部门
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public List<UserDTO> GetUsersByOrgIdWithoutOrg(int id)
        {
            var data = _organizationRepository.GetUsersByOrgIdWithoutOrg(id);
            return Mapper.Map<List<UserDTO>>(data);
        }


        /// <summary>
        /// 根据部门范围获取其下人员
        /// </summary>
        /// <param name="startDeptFid"></param>
        /// <param name="endDeptFid"></param>
        /// <returns></returns>
        public List<UserDTO> GetUsersByOrgRange(Guid startDeptFid, Guid endDeptFid)
        {
            //根据部门fid,其createdate,再根据其满足startdept的createdate<=result <=enddept的createdate 条件下的部门下的人员

            //部门范围

            var deptrange = _organizationRepository.FindAll(o => o.Status == 0).ToList();
            if (!startDeptFid.Equals(Guid.Empty))
            {
                var startdept = GetOrganizationByFid(startDeptFid.ToString());
                if (startdept != null)
                {
                    deptrange = _organizationRepository.Find(o => o.Status == 0 && o.CreatedDate.CompareTo(startdept.CreatedDate) >= 0).ToList();
                    //deptrange = allorg.Where(o => o.CreatedDate >= startdept.CreatedDate).ToList();
                }
            }
            if (!endDeptFid.Equals(Guid.Empty))
            {
                var enddept = GetOrganizationByFid(endDeptFid.ToString());
                if (enddept != null)
                {
                    deptrange = deptrange.Where(o => o.CreatedDate.CompareTo(enddept.CreatedDate) <= 0).ToList();
                    //deptrange = deptrange.Count > 0 ? deptrange.Where(o => o.CreatedDate.CompareTo(enddept.CreatedDate) <= 0).ToList() : allorg.Where(o => o.CreatedDate.CompareTo(enddept.CreatedDate) <= 0).ToList();
                    //deptrange = deptrange.Count > 0 ? deptrange.Where(o => o.CreatedDate <= enddept.CreatedDate).ToList() : allorg.Where(o => o.CreatedDate <= enddept.CreatedDate).ToList();
                }
            }


            //根据部门范围取其下挂人员--sys_AspNetUsersInOrganization
            var userList = new List<UserDTO>();
            if (deptrange.Count <= 0) return userList;

            //var deptfids = new List<int>();
            deptrange.ForEach((Action<Organization>)(o =>
            {
                var org = GetOrganizationByFid((string)o.ReferenceId1);

                userList.AddRange(GetUsersByOrgIdWithoutOrg(org.id));

            }));

            return userList.Distinct(u => u.UserId).ToList();
        }

        #endregion

        #region UserTracingLogDTO

        public PaginatedBaseDTO<UserTracingLogDTO> LoadPaginatedUserTracingLogs(int pageIndex, int pageSize, string name, string order)
        {
            Expression<Func<UserTracingLog, bool>> predicate = m => true;
            if (!string.IsNullOrWhiteSpace(name))
            {
                predicate = predicate.And(m => m.Operator.Contains(name));
            }

            var data = _userTracingLogRepository.FindPagenatedListWithCount<UserTracingLog>(
                pageIndex,
                pageSize,
                predicate,
                "OperateDate",
                order.Equals("asc"));

            var total = data.Item1;
            var rows = Mapper.Map<List<UserTracingLogDTO>>(data.Item2);
            return new PaginatedBaseDTO<UserTracingLogDTO>(pageIndex, pageSize, total, rows);
        }

        #endregion

        #region 测试TreeNode基类
        public List<OrganizationDTO> Test_GetAllTreeNodeWithNestChild()
        {
            var result = _organizationRepository.GetAllTreeNodeWithNestChild();

            return Mapper.Map<List<OrganizationDTO>>(result);
        }

        public OrganizationDTO Test_GetTreeNodeWithNestChildById(int id)
        {
            var result = _organizationRepository.GetTreeNodeWithNestChildById(id);

            return Mapper.Map<OrganizationDTO>(result);
        }

        public List<OrganizationDTO> Test_GetTreeNodesWithNestParentAndChildById(int id)
        {
            var result = _organizationRepository.GetTreeNodesWithNestParentAndChildById(id);

            return Mapper.Map<List<OrganizationDTO>>(result);
        }

        public List<OrganizationDTO> Test_GetTreeNodesWithNestParentAndChildByFilter(string name)
        {
            Expression<Func<Organization, bool>> predicate = m => !m.IsDeleted;
            if (!string.IsNullOrEmpty(name))
                predicate = predicate.And(m => m.Name.Contains(name));
            var result = _organizationRepository.GetTreeNodesWithNestParentAndChildByFilter(predicate);

            return Mapper.Map<List<OrganizationDTO>>(result);
        }

        public bool Test_UpdateExtendFields()
        {
            var result = _organizationRepository.UpdateExtendFields();

            return result;
        }
        #endregion

    }
}
